﻿ #region Disclaimer/Info
 
 /////////////////////////////////////////////////////////////////////////////////////////////////
 //
 //   File:		EntityBase.cs
 //   Website:		http://dexterblogengine.com/
 //   Authors:		http://dexterblogengine.com/About.ashx
 //   Rev:		1
 //   Created:		19/01/2011
 //   Last edit:		19/01/2011
 //   License:		GNU Library General Public License (LGPL)
 //   File:            EntityBase.cs
 //   For updated news and information please visit http://dexterblogengine.com/
 //   Dexter is hosted to Codeplex at http://dexterblogengine.codeplex.com
 //   For any question contact info@dexterblogengine.com
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #endregion
 
using System;

namespace Dexter.Domain.Model {
	/// <summary>
	/// 	The base class for all domain entities
	/// </summary>
	/// <remarks>
	/// 	Equality operators added to supply a good support for NHibernate
	/// 	which need to rely on a form of identity equality
	/// </remarks>
	public class EntityBase : DomainEntity {
		/// <summary>
		/// 	Initializes a new instance of the <see cref = "EntityBase" /> class.
		/// </summary>
		protected EntityBase ( ) {}

		/// <summary>
		/// 	Gets or sets the record Id.
		/// </summary>
		/// <value>The Id.</value>
		public virtual int Id { get; set; }

		/// <summary>
		/// 	Gets or sets the creation date.
		/// </summary>
		/// <value>The creation date.</value>
		public virtual DateTime CreationDate { get; set; }

		/// <summary>
		/// 	Gets or sets the update date.
		/// </summary>
		/// <value>The update date.</value>
		public virtual DateTime? UpdateDate { get; set; }

		/// <summary>
		/// 	Gets a value indicating whether this instance is transient.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this instance is transient; otherwise, <c>false</c>.
		/// </value>
		public virtual bool IsTransient {
			get { return Id == 0; }
		}

		/// <summary>
		/// 	Determines whether the specified <see cref = "System.Object" /> is equal to this instance.
		/// </summary>
		/// <param name = "obj">The <see cref = "System.Object" /> to compare with this instance.</param>
		/// <returns>
		/// 	<c>true</c> if the specified <see cref = "System.Object" /> is equal to this instance; otherwise, <c>false</c>.
		/// </returns>
		/// <exception cref = "T:System.NullReferenceException">
		/// 	The <paramref name = "obj" /> parameter is null.
		/// </exception>
		public override bool Equals ( object obj ) {
			if ( ReferenceEquals ( null , obj ) ) {
				return false;
			}
			if ( ReferenceEquals ( this , obj ) ) {
				return true;
			}

			if ( !( obj is EntityBase ) ) {
				return false;
			}

			var other = obj as EntityBase;

			if ( IsTransient || other.IsTransient ) {
				return false;
			}

			return other.Id == Id;
		}

		/// <summary>
		/// 	Returns a hash code for this instance.
		/// </summary>
		/// <returns>
		/// 	A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
		/// </returns>
		public override int GetHashCode ( ) {
			return Id;
		}

		/// <summary>
		/// 	Implements the operator ==.
		/// </summary>
		/// <param name = "left">The left.</param>
		/// <param name = "right">The right.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator == ( EntityBase left , EntityBase right ) {
			return Equals ( left , right );
		}

		/// <summary>
		/// 	Implements the operator !=.
		/// </summary>
		/// <param name = "left">The left.</param>
		/// <param name = "right">The right.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator != ( EntityBase left , EntityBase right ) {
			return !Equals ( left , right );
		}
	}
}
